// 假设为第三方服务

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"sync"
	"time"
)

const (
	LimitTimeFrequency = 10   // 单位:秒，限制时间频率
	LimitTheAmountSent = 1000 // 限制发送量
)

var limiter = newSlidingWindowLimiter(LimitTimeFrequency * time.Second)

// 滑动窗口限流器
type slidingWindowLimiter struct {
	mu       sync.Mutex
	window   []int // 窗口大小为1分钟，60秒
	count    int   // 当前窗口内已发送的短信数量
	interval time.Duration
}

// 创建滑动窗口限流器
func newSlidingWindowLimiter(interval time.Duration) *slidingWindowLimiter {
	return &slidingWindowLimiter{
		interval: interval,
		window:   make([]int, LimitTimeFrequency),
	}
}

// 滑动窗口限流
func (limiter *slidingWindowLimiter) limit() bool {
	limiter.mu.Lock()
	defer limiter.mu.Unlock()

	now := int(time.Now().Unix())

	// 将当前时间对应的窗口位置计算出来
	index := now % LimitTimeFrequency

	// 如果当前时间与上次更新时间不在同一个窗口，则需要将窗口内已发送的短信数量清零
	if now-limiter.window[index] >= LimitTimeFrequency {
		limiter.window[index] = now
		limiter.count = 1
		return true
	}

	// 如果当前窗口内已发送的短信数量超过了限制，则返回false
	if limiter.count >= LimitTheAmountSent {
		return false
	}

	// 更新窗口内已发送的短信数量
	limiter.window[index] = now
	limiter.count++

	return true
}

const (
	ErrExceedRateLimit = 40001
	ErrSendWrong       = 50000
	Success            = 0
)

type Response struct {
	Code int
	Msg  string
}

func ResponseError(w http.ResponseWriter, code int, msg string) {
	// 返回结果
	res := &Response{
		Code: code,
		Msg:  msg,
	}
	b, _ := json.Marshal(res)
	w.Write(b)
}
func ResponseSuccess(w http.ResponseWriter, msg string) {
	// 返回结果
	res := &Response{
		Code: Success,
		Msg:  msg,
	}
	b, _ := json.Marshal(res)
	w.Write(b)
}

type Message struct {
	Phone   string
	Content string
}

// 定义发送短信
func sendSMS(phone, content string) error {
	// 发送短信的代码
	fmt.Printf("正在给%s发送短信，内容为：%s...\n", phone, content)

	return nil
}

// 短信发送接口
func sendSMSHandler(w http.ResponseWriter, r *http.Request) {
	// 解析请求参数
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		ResponseError(w, ErrSendWrong, "发送短信失败："+err.Error())
		return
	}
	// 解码JSON数据
	var msg Message
	err = json.Unmarshal(body, &msg)
	if err != nil {
		ResponseError(w, ErrSendWrong, "发送短信失败："+err.Error())
		return
	}

	// 滑动窗口限流
	if !limiter.limit() {
		ResponseError(w, ErrExceedRateLimit, "发送短信失败：频率受限")
		return
	}

	// 发送短信
	if err := sendSMS(msg.Phone, msg.Content); err != nil {
		ResponseError(w, ErrSendWrong, "发送短信失败："+err.Error())
		return
	}

	// 返回结果
	ResponseSuccess(w, "发送短信成功")
}

func main() {
	// 注册短信发送接口
	http.HandleFunc("/send_sms", sendSMSHandler)

	// 启动HTTP服务
	if err := http.ListenAndServe(":8080", nil); err != nil {
		fmt.Println("启动HTTP服务失败：", err)
	}
}
